home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / CBGRX100.ARJ / BESTFONT.C < prev    next >
Text File  |  1992-04-10  |  5KB  |  188 lines

  1. /** 
  2.  ** BESTFONT.C 
  3.  **
  4.  **  Copyright (C) 1992, Csaba Biegl
  5.  **    820 Stirrup Dr, Nashville, TN, 37221
  6.  **    csaba@vuse.vanderbilt.edu
  7.  **
  8.  **  This file is distributed under the terms listed in the document
  9.  **  "copying.cb", available from the author at the address above.
  10.  **  A copy of "copying.cb" should accompany this file; if not, a copy
  11.  **  should be available from where this file was obtained.  This file
  12.  **  may not be distributed without a verbatim copy of "copying.cb".
  13.  **  You should also have received a copy of the GNU General Public
  14.  **  License along with this program (it is in the file "copying");
  15.  **  if not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  16.  **  Cambridge, MA 02139, USA.
  17.  **
  18.  **  This program is distributed in the hope that it will be useful,
  19.  **  but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.  **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.  **  GNU General Public License for more details.
  22.  **/
  23.  
  24. #include "grx.h"
  25. #include "libgrx.h"
  26. #include "grxfile.h"
  27. #include "gmalloc.h"
  28.  
  29. #include <string.h>
  30. #include <stdio.h>
  31. #include <io.h>
  32.  
  33.  
  34. #define FNT_USABLE    fnt_internal        /* reuse this flag ! */
  35.  
  36.  
  37. static GrFont *fontDB;
  38. static int DBsize;
  39. static int loaded = FALSE;
  40.  
  41.  
  42. static int load_fontDB(void)
  43. {
  44.     FntDirHdr hdr;
  45.     char fullname[200];
  46.     int  file,size;
  47.  
  48.     _GrGetFname("fonts.dir",_GrFontPath,FNTENV,"",fullname);
  49.     if((file = _GrFileOpen(fullname)) == EOF) return(FALSE);
  50.     if((read(file,&hdr,sizeof(FntDirHdr)) != sizeof(FntDirHdr)) ||
  51.        (hdr.magic != FONTDIR_MAGIC) ||
  52.        ((size = sizeof(GrFont) * (int)hdr.numentries) <= 0) ||
  53.        ((fontDB = _GrMalloc(size)) == NULL) ||
  54.        (read(file,fontDB,size) != size)) {
  55.         if(fontDB != NULL) _GrFree(fontDB);
  56.         _GrFileClose(file);
  57.         return(FALSE);
  58.     }
  59.     _GrFileClose(file);
  60.     DBsize = (int)hdr.numentries;
  61.     return(loaded = TRUE);
  62. }
  63.  
  64. static int match_aux(char *pattern,char *string)
  65. {
  66.     for( ; ; ) {
  67.         switch(*pattern) {
  68.           case '\0':
  69.           case ':':
  70.         return((*string == '\0') ? TRUE : FALSE);
  71.           case '?':
  72.         if(*string == '\0') return(FALSE);
  73.         pattern++;
  74.         string++;
  75.         break;
  76.           case '*':
  77.         for( ; ; ) {
  78.             switch(*++pattern) {
  79.               case '\0':
  80.               case ':':
  81.             return(TRUE);
  82.               case '?':
  83.             if(*string == '\0') return(FALSE);
  84.             string++;
  85.             continue;
  86.               case '*':
  87.             continue;
  88.               default:
  89.             break;
  90.             }
  91.             break;
  92.         }
  93.         for( ; ; ) {
  94.             string = strchr(string,*pattern);
  95.             if(string == NULL) return(FALSE);
  96.             if(match_aux(pattern,string)) return(TRUE);
  97.             string++;
  98.         }
  99.           default:
  100.         if(*pattern != *string) return(FALSE);
  101.         string++;
  102.         pattern++;
  103.         }
  104.     }
  105. }
  106.  
  107. static int match(char *pattern,char *string)
  108. {
  109.     while(*pattern != '\0') {
  110.         if(match_aux(pattern,string)) return(TRUE);
  111.         pattern = strchr(pattern,':');
  112.         if(pattern == NULL) return(FALSE);
  113.         pattern++;
  114.     }
  115.     return(FALSE);
  116. }
  117.  
  118. GrTextOption *GrFindBestFont(int width,int height,int magnify,
  119.                  char *family,GrTextOption *where)
  120. {
  121.     GrFont *f;
  122.     int error = TRUE;
  123.     int found = (-1);
  124.     int ii,minerr;
  125.  
  126.     if(!loaded && !load_fontDB()) return(NULL);
  127.     for(f = fontDB,ii = 0; ii < DBsize; f++,ii++) {
  128.         if((f->fnt_height <= height) &&
  129.            (!f->fnt_isfixed || (f->fnt_width <= width)) &&
  130.            (match(family,f->fnt_family))) {
  131.         f->FNT_USABLE = TRUE;
  132.         error = FALSE;
  133.         if((f->fnt_height == height) &&
  134.            (!f->fnt_isfixed || (f->fnt_width == width))) {
  135.             magnify = FALSE;
  136.             found   = ii;
  137.             break;
  138.         }
  139.         }
  140.         else f->FNT_USABLE = FALSE;
  141.     }
  142.     if(error) return(NULL);
  143.     if(found < 0) {
  144.         minerr = 32000;
  145.         for(f = fontDB,ii = 0; ii < DBsize; f++,ii++) {
  146.         if(!f->FNT_USABLE) continue;
  147.         if(!magnify) {
  148.             error = height - f->fnt_height;
  149.             if(f->fnt_isfixed) error += width - f->fnt_width;
  150.         }
  151.         else {
  152.             int magn = height / f->fnt_height;
  153.             int size = magn * f->fnt_height;
  154.             error = (height - size) + (2 * --magn);
  155.             if(f->fnt_isfixed) {
  156.             magn = width / f->fnt_width;
  157.             size = magn * f->fnt_width;
  158.             error += (width - size) + (2 * --magn);
  159.             }
  160.         }
  161.         if(error < minerr) {
  162.             found  = ii;
  163.             minerr = error;
  164.         }
  165.         }
  166.     }
  167.     f = GrLoadFont(fontDB[found].fnt_name);
  168.     if(f == NULL) return(NULL);
  169.     if(where == NULL) {
  170.         where = _GrMalloc(sizeof(GrTextOption));
  171.         if(where == NULL) return(NULL);
  172.     }
  173.     memset(where,0,sizeof(GrTextOption));
  174.     where->txo_font = f;
  175.     if(!magnify) {
  176.         where->txo_xmag = 1;
  177.         where->txo_ymag = 1;
  178.     }
  179.     else {
  180.         where->txo_ymag = height / f->fnt_height;
  181.         where->txo_xmag = f->fnt_isfixed ?
  182.         width / f->fnt_width :
  183.         where->txo_ymag;
  184.     }
  185.     return(where);
  186. }
  187.  
  188.